﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OhioState.Tiling;

using UnityEngine;

namespace OhioState.Tiling
{
    class PerlinNoiseTilingBuilder : ITilingBuilder<Texture2D>
    {
        public int Height
        {
            get{ return height;}
        }
        public int Width
        {
            get{return Width;}
        }
        public PerlinNoiseTileSet TileSet
        {
            get { return tileSet; }
        }
        public PerlinNoiseTilingBuilder(int width, int height, PerlinNoiseTileSet tileSet)
        {
            this.width = width;
            this.height = height;
            this.tileSet = tileSet;
        }
        public ITiling<Texture2D> BuildTiling()
        {
            PerlinNoiseTile[] layout = new PerlinNoiseTile[width * height];
            List<Tuple<Direction, List<int>>> edgeConstraints = new List<Tuple<Direction, List<int>>>();

            System.Random rng = new System.Random(25535);
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    edgeConstraints.Clear();
                    if (i == 0 && j == 0)
                    {
                        layout[0] = (PerlinNoiseTile)tileSet.GetTile(rng.Next(tileSet.NumberOfTiles));
                        continue;
                    }
                    if (i != 0)
                    {
                        PerlinNoiseTile bottom = (PerlinNoiseTile)layout[(i - 1) * width + j];
                        Tuple<Direction, List<int>> tp = new Tuple<Direction, List<int>>(Direction.S, bottom.GetEdgeColor(Direction.N));
                        edgeConstraints.Add(tp);
                    }
                    if (j != 0)
                    {
                        PerlinNoiseTile left = (PerlinNoiseTile)layout[i * width + j - 1];
                        Tuple<Direction, List<int>> tp = new Tuple<Direction, List<int>>(Direction.W, left.GetEdgeColor(Direction.E));
                        edgeConstraints.Add(tp);
                    }
                  
                    PerlinNoiseTileSet noiseTileSet = (PerlinNoiseTileSet) tileSet;
                    IEnumerable<PerlinNoiseTile> matched = noiseTileSet.MatchingTiles(edgeConstraints) as IEnumerable<PerlinNoiseTile>;
                    int idx = rng.Next(matched.Count());
                    
                    
                    Debug.Log("matched " + matched.Count().ToString() + "choose " + idx.ToString());
                    PerlinNoiseTile noiseTile = matched.ElementAt(idx);
                    //noiseTile.Print();
                    layout[i * width + j] = noiseTile;
                }
            }
            List<ITile<Texture2D>> tiling = new List<ITile<Texture2D>>();
            for(int i=0;i<width*height;i++)
            {
                tiling.Add((ITile<Texture2D>) layout[i]);
            }
            GridTiling<Texture2D> gridTiling = new GridTiling<Texture2D>(width, height, tiling);
            return (ITiling<Texture2D>)gridTiling;
        }
        private int width;
        private int height;
        private PerlinNoiseTileSet tileSet;
    }
}
